package com.wlyuan.open.application.service;

import com.wlyuan.core.exception.AssertUtils;
import com.wlyuan.core.exception.ValueError;
import com.wlyuan.core.marker.NamedStatus;
import com.wlyuan.mybatis.query.PageUtils;
import com.wlyuan.open.api.IOpenApiService;
import com.wlyuan.open.application.translator.OpenApiTranslator;
import com.wlyuan.open.core.exception.OpenApiNotFoundException;
import com.wlyuan.open.domain.api.factory.OpenApiFactory;
import com.wlyuan.open.domain.api.respository.OpenApiRepository;
import com.wlyuan.open.domain.api.valueobj.OpenApiId;
import com.wlyuan.open.dto.api.*;
import com.wlyuan.open.vo.OpenApiDetailVO;
import com.wlyuan.utils.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.apache.dubbo.config.annotation.DubboService;

import java.util.Optional;

/**
 * @author lijing
 * @description
 */
@DubboService
@Slf4j
@RequiredArgsConstructor
public class OpenApiServiceImpl implements IOpenApiService {
    private final OpenApiFactory openApiFactory;
    private final OpenApiRepository openApiRepository;

    @Override
    public void create(OpenApiCreationDTO creation) {
        var api = openApiRepository.getByUrl(creation.getUrl(), creation.getMethod());
        if (Optional.ofNullable(api).isPresent()) {
            throw new ValueError("接口已存在");
        }
        openApiFactory.create(creation);
    }

    @Override
    public Page<OpenApiDetailVO> search(OpenApiFilterDTO filter) {
        var result = openApiRepository.search(filter);
        return PageUtils.as(result, OpenApiTranslator.translate(openApiRepository.list(result.getRecords())));
    }

    @Override
    public Page<OpenApiDetailVO> getAllInvalidApi(OpenApiFilterDTO filter) {
        filter.setStatus(NamedStatus.ENABLED.getValue());
        var result = openApiRepository.search(filter);
        return PageUtils.as(result, OpenApiTranslator.translate(openApiRepository.list(result.getRecords())));
    }

    @Override
    public OpenApiDetailVO getApiId(Long apiId) {
        var openApiId = new OpenApiId(apiId);
        var openApi = openApiRepository.ofId(openApiId);
        AssertUtils.assertNotNull(openApi, new OpenApiNotFoundException(), openApiId);
        return OpenApiTranslator.translate(openApi);
    }

    @Override
    public void enable(OpenApiEnableDTO enable) {
        var openApiId = new OpenApiId(enable.getApiId());
        var openApi = openApiRepository.ofId(openApiId);
        AssertUtils.assertNotNull(openApi, new OpenApiNotFoundException(), openApiId);
        openApi.enable(enable.getUser());
        openApiRepository.save(openApi);
    }

    @Override
    public void disable(OpenApiDisableDTO disable) {
        var openApiId = new OpenApiId(disable.getApiId());
        var openApi = openApiRepository.ofId(openApiId);
        AssertUtils.assertNotNull(openApi, new OpenApiNotFoundException(), openApiId);
        openApi.disable(disable.getUser());
        openApiRepository.save(openApi);
    }

    @Override
    public void update(OpenApiUpdateDTO update) {
        var openApiId = new OpenApiId(update.getApiId());
        var api = openApiRepository.ofId(openApiId);
        AssertUtils.assertNotNull(api, new OpenApiNotFoundException(), openApiId);
        var ofApi = openApiRepository.getByUrl(update.getUrl(), update.getMethod());
        if (Optional.ofNullable(ofApi).isPresent() && !ofApi.getId().equals(openApiId)) {
            throw new ValueError("接口已存在");
        }
        api.change(update);
        openApiRepository.save(api);
    }

    @Override
    public OpenApiDetailVO getByUrlMethod(String url, String method) {
        return OpenApiTranslator.translate(openApiRepository.getByUrl(url, method));
    }
}
